package com.hserver.docker.service.impl;

import com.hserver.docker.bean.Deploy;
import com.hserver.docker.config.ConstConfig;
import com.hserver.docker.service.GitService;
import com.hserver.docker.service.LogService;
import com.hserver.docker.utils.FileUtil;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.CloneCommand;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.LsRemoteCommand;
import org.eclipse.jgit.api.TransportConfigCallback;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.transport.*;
import org.eclipse.jgit.util.FS;
import cn.hserver.core.ioc.annotation.Autowired;
import cn.hserver.core.ioc.annotation.Bean;

import java.io.File;
import java.util.UUID;

/**
 * @author hxm
 */
@Slf4j
@Bean
public class GitServiceImpl implements GitService {


    @Autowired
    private LogService logService;

    @Override
    public Boolean cloneProject(Deploy deploy, String recordId) {
        log.debug("git clone start");
        logService.add(recordId, "移除旧代码");
        FileUtil.deleteFolder(ConstConfig.PROJECT_PATH + deploy.getUuid());
        logService.add(recordId, "开始拉取仓库代码");
        if (deploy.getPrivateKey() != null && deploy.getPrivateKey().trim().length() > 0 && deploy.getUrl().startsWith("git")) {
            return gitSsh(deploy, recordId);
        } else {
            return gitHttp(deploy, recordId);
        }
    }

    private boolean gitSsh(Deploy deploy, String recordId) {
        String keyPath = ConstConfig.PATH + "key" + File.separator + UUID.randomUUID().toString() + ".txt";
        FileUtil.writeKey(keyPath, deploy.getPrivateKey().trim());
        final SshSessionFactory sshSessionFactory = new JschConfigSessionFactory() {
            @Override
            protected void configure(OpenSshConfig.Host host, Session session) {
                java.util.Properties config = new java.util.Properties();
                config.put("StrictHostKeyChecking", "no");
                session.setConfig(config);
            }

            @Override
            protected JSch createDefaultJSch(FS fs) throws JSchException {
                JSch defaultJSch = super.createDefaultJSch(fs);
                defaultJSch.addIdentity(keyPath);
                return defaultJSch;
            }
        };
        CloneCommand cloneCommand = Git.cloneRepository();
        cloneCommand.setURI(deploy.getUrl());
        cloneCommand.setBranch(deploy.getBranch());
        cloneCommand.setDirectory(new File(ConstConfig.PROJECT_PATH + deploy.getUuid()));
        cloneCommand.setTransportConfigCallback(transport -> {
            SshTransport sshTransport = (SshTransport) transport;
            sshTransport.setSshSessionFactory(sshSessionFactory);
        });
        try {
            cloneCommand.call().close();
            logService.add(recordId, "仓库代码拉取完成");
            return true;
        } catch (GitAPIException e) {
            e.printStackTrace();
            logService.add(recordId, "仓库代码拉取异常");
            logService.add(recordId, e.getLocalizedMessage());
            logService.add(recordId, e.getMessage());
            return false;
        } finally {
            new File(keyPath).delete();
        }
    }

    private boolean gitHttp(Deploy deploy, String recordId) {
        UsernamePasswordCredentialsProvider usernamePasswordCredentialsProvider = null;
        if (deploy.getPassword() != null && deploy.getPassword() != null) {
            usernamePasswordCredentialsProvider = new
                    UsernamePasswordCredentialsProvider(deploy.getUserName(), deploy.getPassword());
        }
        //克隆代码库命令
        CloneCommand cloneCommand = Git.cloneRepository();
        try {
            cloneCommand.setURI(deploy.getUrl())
                    .setBranch(deploy.getBranch())
                    .setDirectory(new File(ConstConfig.PROJECT_PATH + deploy.getUuid()))
                    .setCredentialsProvider(usernamePasswordCredentialsProvider)
                    .call()
                    .close();
            logService.add(recordId, "仓库代码拉取完成");
            return true;
        } catch (GitAPIException e) {
            e.printStackTrace();
            logService.add(recordId, "仓库代码拉取异常");
            logService.add(recordId, e.getMessage());
            logService.add(recordId, e.getLocalizedMessage());
            return false;
        }
    }

}
